﻿using System;
using System.Linq;
using System.Management.Automation;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace DotNet.DevOps.Tasks.Tests.AcceptanceTest_Powershell
{
    internal class PowershellRunner
    {
        public static void RunScript(ITask task)
        {
            var tasks = new PSDataCollection<ITask> { task };

            using (var ps = PowerShell.Create())
            {
                ps.Runspace.SessionStateProxy.SetVariable("taskList", tasks);
                ps.AddScript(@"$taskList | ForEach { $_.Execute()}");
                ps.AddCommand("Out-String");
                var output = ps.Invoke();

                var stringBuilder = new StringBuilder();
                foreach (var obj in output)
                {
                    stringBuilder.AppendLine(obj.ToString());
                }

                var result = stringBuilder.ToString().Trim();

                if (result.Contains("False"))
                {
                    throw new Exception(string.Format("Error executing Powershell script: {0}", result));
                }

                if (result.Contains("True") == false && result.Contains("False") == false)
                {
                    throw new Exception(string.Format("Error executing Powershell script: {0}", result));
                }
            }
        }

        public static void RunScript(Cmdlet cmdlet)
        {
            var collection = new PSDataCollection<Cmdlet> {cmdlet};

            using (var ps = PowerShell.Create())
            {
                ps.Runspace.SessionStateProxy.SetVariable("taskList", collection);
                ps.AddScript(string.Format("$taskList | ForEach {{ $_.{0}()}}","Invoke"));
                ps.Invoke();

                var stringBuilder = new StringBuilder();

                ps.Streams.Debug.ReadAll().ToList().ForEach(dbg => stringBuilder.AppendLine(dbg.Message));
                ps.Streams.Progress.ReadAll().ToList().ForEach(prg => stringBuilder.AppendLine(prg.ToString()));
                ps.Streams.Verbose.ReadAll().ToList().ForEach(ver => stringBuilder.AppendLine(ver.Message));
                ps.Streams.Warning.ReadAll().ToList().ForEach(war => stringBuilder.AppendLine(war.Message));

                if (ps.Streams.Error.Count > 0)
                {
                    ps.Streams.Error.ReadAll().ToList().ForEach(err => stringBuilder.AppendLine(err.Exception.Message));
                    throw new Exception(string.Format("Error executing Powershell script: {0}", stringBuilder.ToString()));
                }
                Console.WriteLine(stringBuilder.ToString());
            }
        }
    }
}